package com.crdeng.system.security;

import com.crdeng.Utils.MD5Util;
import com.crdeng.system.entity.Menu;
import com.crdeng.system.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;


@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MemberDetailsService memberDetailsService;
    @Autowired
    private MenuService menuService;


    /**
     * 添加授权账号
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        //auth.inMemoryAuthentication().withUser("crdeng").password("crdeng1").authorities("/");
     /*   auth.inMemoryAuthentication().
                withUser("crdeng").password("crdeng1").authorities("addMember",
                "delMember", "updateMember", "showMember");
        auth.inMemoryAuthentication().
                withUser("admin").password("admin").authorities("addMember");*/
        auth.userDetailsService(memberDetailsService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return MD5Util.encode((String) charSequence);
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                String rawPass = MD5Util.encode((String) charSequence);
                boolean result = rawPass.equals(s);
                return result;
            }


        });


    }

    /**
     * 配置HttpSecurity 拦截资源
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        List<Menu> list = menuService.list();
//    http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
        // http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry EIR = http.authorizeRequests();

        list.forEach((menu) -> {
            if (!StringUtils.isEmpty(menu.getUrl()) && !StringUtils.isEmpty(menu.getPerms())) {
                EIR.antMatchers(menu.getUrl()).hasAnyAuthority(menu.getPerms());
            }
        });
        EIR.antMatchers("/login").permitAll()
                // swagger start
                .antMatchers("/swagger-resources/**","/api-docs","/doc.html","/api-docs-ext","/webjars/**","/v2/**","/swagger-ui.html") //配置地址放行
                .permitAll()
               // swagger end
                .antMatchers("/**").fullyAuthenticated()
                .and()
                .addFilter(new JWTValidationFilter(authenticationManager()))
                .addFilter(new JWTLoginFilter(authenticationManager())).csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and();
    }

    @Override
    public void configure(WebSecurity web) {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/swagger-resources/**","/api-docs","/doc.html","/api-docs-ext","/webjars/**","/v2/**","/swagger-ui.html");
    }
}
